﻿#include <iostream>

#include <boost/math/distributions/normal.hpp>

#include "Sample.h"

using namespace std;
using namespace sample;


void test_RandomSample()
{
    SampleManager sm;

    sample::SampleFrame& p = sm.addSampleFrame("test random");

    sample::ColumnData c;
    for (int i = 0; i < 1000; ++i) {
        c.push_back(i);
    }
    sample::Metric m("age", Metric::TypeInt);
    p.setData(m, c);

    SampleDesignPtr sd(new RandomSample(p));
    sm.addSampleDesign(sd);
    sd->setMetric("age");
    sd->setRelativeError(0.05);
    sd->calcSampleSize();
    SampleResult* result = sd->sample();          
    assert(result->sampleDesign == sd.get());
    assert(result->results.size() == 1);
    assert(result->results.begin()->first == "random");
    for (auto& row : result->results.begin()->second) {
        std::cout << row << " ";
    }
    std::cout << std::endl;



    // test 分层抽样
    sample::SampleFrame& ps = sm.addSampleFrame("test StratifiedSample");
    ps.setData(m, c);

    StratifiedSample* ssd = new StratifiedSample(p);
    sm.addSampleDesign(SampleDesignPtr(ssd));
    ssd->setMetric("age");

    ssd->setLayeringInfo("age", 0, 5);
    ssd->calcLayerPopulationSize();
    auto& layerInfo = ssd->getLayerInfo();
    assert(layerInfo.size() == 5);
    auto li = layerInfo.find("1");
    assert(li->second.populationSize == 200);

    ssd->calcLayerSampleSizeByTotalSize(900,  "age", StratifiedSample::SampleConfigTypeEven);
    assert(li->second.sampleSize == 900/5);
    li = layerInfo.find("4");
    assert(li->second.sampleSize == 900 - 4*900/5);
    
    result = ssd->sample();
    assert(result->sampleDesign == ssd);
    assert(result->results.size() == 5);
    assert(result->results.begin()->first == "1");
    for (auto& row : result->results.begin()->second) {
        std::cout << row << " ";
    }
    std::cout << std::endl;

    ssd->setRelativeError(0.05);
    ssd->calcSampleSize();
}


int main(int argc, char* argv[])
{
    boost::math::normal_distribution<> normal(0.0, 1.0);        // 均值0 标准差1
    cout << boost::math::cdf(normal, 1.96) << endl;
    cout << boost::math::cdf(boost::math::complement(normal, 1.96)) << endl; // 1-cdf
    cout << boost::math::cdf(normal, 1) - boost::math::cdf(normal, -1) << endl;
    cout << boost::math::quantile(normal, 0.975002) << endl;    // 分位点
    cout << "Hello world!" << endl;

    test_RandomSample();
    
    return 0;
}
/*
output:
0.975002
0.0249979
0.682689
1.96
Hello world!
*/